package hit.core;

import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

public class ProductContainerTest {
	
	ProductContainer su1, su2, pg1, pg2;
	public ProductContainerTest() {
	}
	
	@Before
	public void setUp() {
		su1 = new StorageUnit("Storage Unit 1");
		su2 = new StorageUnit("Storage Unit 2");
		
		pg1 = new ProductGroup("Product Group 1");
		((ProductGroup)pg1).SetThreeMonth(new Size(1, Size.Unit.COUNT));
		pg2 = new ProductGroup("Product Group 2");
		((ProductGroup)pg2).SetThreeMonth(new Size(1, Size.Unit.COUNT));
	}

	@Test
	public void testAddProductGroup() {
		try{
			su1.AddProductGroup(null);
			fail("Incorrectly able to add null product group.");
		}
		catch (IllegalArgumentException e){}
		
		try{
			((ProductGroup)pg1).SetParentContainer(su2);
			su1.AddProductGroup((ProductGroup)pg1);
		}
		catch (IllegalArgumentException e){
			fail("Unable to add product group.");
		}
	}

	@Test
	public void testGetName() {
		assertEquals("Storage Unit 2", su2.GetName());
	}

	@Test
	public void testSetName() {
		try{
			su1.SetName("");
			fail("Incorrectly able to set name to blank.");
		}
		catch (IllegalArgumentException e){}
		
		try{
			su1.SetName("New Storage Unit Name");
		}
		catch (IllegalArgumentException e){
			fail("Unable to set name.");
		}
	}

	/*@Test
	public void testGetProductGroupIterator() {
		System.out.println("GetProductGroupIterator");
		ProductContainer instance = null;
		Iterator expResult = null;
		Iterator result = instance.GetProductGroupIterator();
		assertEquals(expResult, result);
		fail("The test case is a prototype.");
	}*/

	@Test
	public void testCanRemoveProductGroup() {
		((ProductGroup)pg1).SetParentContainer(su1);
		assertFalse("Can remove a product group that isn't in productGroups.", 
				su1.CanRemoveProductGroup((ProductGroup)pg1));
		su1.AddProductGroup((ProductGroup)pg1);
		assertTrue("You ought to be able to delete Product Group 1", 
				su1.CanRemoveProductGroup((ProductGroup)pg1));
	}

	@Test
	public void testRemoveProductGroup() {
		((ProductGroup)pg1).SetParentContainer(su1);
		su1.AddProductGroup((ProductGroup)pg1);
		assertEquals(true, su1.RemoveProductGroup((ProductGroup)pg1));
		
		((ProductGroup)pg2).SetParentContainer(pg1);
		pg1.AddProductGroup((ProductGroup)pg2);
		assertEquals(true, pg1.RemoveProductGroup((ProductGroup)pg2));
		
		try{
			su2.AddProductGroup((ProductGroup)pg1);
			su2.RemoveProductGroup((ProductGroup)pg2);
			fail("Incorrectly removes a productGroup that isn't a child of the storageUnit.");
		}
		catch (IllegalArgumentException e){}
	}

	@Test
	public void testUpdateProductGroup() {
		try{
			su1.UpdateProductGroup((ProductGroup)pg1, (ProductGroup)pg2);
			fail("Updates a product group not currently in the list.");
		}
		catch (IllegalArgumentException e){}
		
		try{
			((ProductGroup)pg1).SetParentContainer(su1);
			su1.AddProductGroup((ProductGroup)pg1);
			((ProductGroup)pg2).SetParentContainer(su2);
			((ProductGroup)pg2).SetThreeMonth(new Size());
			su1.UpdateProductGroup((ProductGroup)pg1, (ProductGroup)pg2);
		}
		catch (IllegalArgumentException e){
			fail("Throws on update when it shouldn't.");
		}
		assertEquals(su1.GetProductGroupIterator().next().GetName(), pg2.GetName());
		assertFalse(su1.GetProductGroupIterator().next().equals(pg2));
	}

	/*public class ProductContainerImpl extends ProductContainer {

		public ProductContainerImpl() {
			super("");
		}
	}*/
}
